

//============ 构造函数严格模式下 必须使用 new 调用 否则会报错
function Food () {
    'use strict';
    // 声明一个构造函数的流程 4 步骤
    //1. const temp = {};
    //2. this = temp;
    // // 原型绑定
    //3. this.__proto__ = Food.prototype;

    this.name = 'shiwu ';
    // 如果显示返回一个对象 会保留返回的 对象 忽略 this
    // return { name: 'zhangsdan ' };
    // 如果返回的不是一个对象 会忽略此返回值 返回 this
    // return 'zhangdan';
    //4. return this  隐式返回
}
// Food()      // TypeError: Cannot set properties of undefined (setting 'name')
new Food();
console.log(new Food());

//======= class 默认为严格模式函数，因此也必须使用 new 调用
// class Cirle {
//     // 构造器
//     constructor(center, radius) {
//         this.center = center
//         this.radius = radius
//     }
//     // 方法
//     calculateCircumference () {
//         return 2 * Math.PI * this.radius
//     }
// }
// Cirle()  // Class constructor Cirle cannot be invoked without 'new'





// ========
class Shape {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    move (x, y) {
        this.x += x;
        this.y += y;
    }
}

// 使用 extends 简历 class 之间的继承关系继承 

class Cirle extends Shape {
    // 构造器
    constructor(center, radius) {
        super(...center);
        this.center = center;
        this.radius = radius;
        this.calculateCircumference = this.calculateCircumference.bind(this);
    }
    // 方法
    calculateCircumference () {
        return 2 * Math.PI * this.radius;
    }
}

// 一级关系 一个类生成一个模板
// 一个父类 => 一个子类 .... => 第 n 个子类 => n个实例
// class 类能够轻松实现类与类之间的继承
const cirle = new Cirle([1, 1], 10);
console.log('cirle', cirle.calculateCircumference());
const newFn = cirle.calculateCircumference;
// === 报错原因是因为新生成的 newFn this 指向改变 window下没有 radius这个属性 解决方案：在 Cirle 类 生成的时候 定义一个改变 this 指向的新函数
newFn();  //TypeError: Cannot read properties of undefined (reading 'radius')
cirle.move(2, 2);
console.log('cirlecirle', cirle.x, cirle.y); // 1,1